﻿namespace Cellfish.Toolbox.Tasks
{
    using System;
    using System.Threading.Tasks;

    /// <summary>
    /// Extension methods to convert Task to Task&lt;T&gt;.
    /// </summary>
    public static class WithResultExtensions
    {
        /// <summary>
        /// Converts a Task object to Task&lt;T&gt;. The result will have the default value of <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">The type the result should have.</typeparam>
        /// <param name="task">The task to convert.</param>
        /// <returns>A task that represents the completion of the supplied task with a result added.</returns>
        /// <exception cref="System.ArgumentNullException">If task is null.</exception>
        public static Task<T> WithResult<T>(this Task task)
        {
            return task.WithResult(default(T));
        }

        /// <summary>
        /// Converts a Task object to Task&lt;T&gt;.
        /// </summary>
        /// <typeparam name="T">The type the result should have.</typeparam>
        /// <param name="task">The task to convert.</param>
        /// <param name="value">The result value of the converted task.</param>
        /// <returns>A task that represents the completion of the supplied task with a result added.</returns>
        /// <exception cref="System.ArgumentNullException">If task is null.</exception>
        public static Task<T> WithResult<T>(this Task task, T value)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            return AddResult(task, value);
        }

        private static async Task<T> AddResult<T>(Task task, T value)
        {
            await task.ConfigureAwait(false);
            return value;
        }
    }
}
